//
//  XWHADeviceCenter.swift
//  XWHAOfflineFitting
//
//  Created by edy on 2024/1/23.
//

import Foundation


class XWHADeviceCenter {
    
    static let center: XWHADeviceCenter = XWHADeviceCenter()
    
    class var deviceManager: XWHearingAidManager {
        Self.center.deviceManager
    }
    
    var deviceManager: XWHearingAidManager {
        XWHearingAidManager.shared
    }
    
    lazy var userDeviceListManager = XWUserConnectDeviceManager()
    
    var rcDevice: XWDeviceModel?
    
    private var connectDelegateList: [XWConnectDeviceDelegate] = []
    
    private(set) var deviceInUse: XWHAModel?
    
    var isReportBindInfoSuccess = false

    // 当前连接的设备
    var conHaDevice: XWHAModel? {
        deviceManager.haDevice
    }
    var conOneDevice: XWHAControlModel? {
        conHaDevice?.oneConnectedDevice
    }
    
    // 连接历史记录列表
    var htDeviceList: [XWDeviceModel] {
        userDeviceListManager.deviceList
    }
    var htDevice: XWDeviceModel? {
        if let fMaster = htDeviceList.first(where: { $0.hasMaster == 1 }) {
            return fMaster
        }
            
        return htDeviceList.first
    }

    var historyHaDevice: XWHAModel? {
//        XWHADataManager.shared.getCurrentHADevice()
        guard let reqDevice = htDevice else {
            return nil
        }
        return getHADeviceInfo(mergeMacDevice: reqDevice)
    }
    
    var switchOnForNone: Bool {
        if htDevice == nil {
            return true
        }
        
        return false
    }
    
    deinit {
        XWHearingAidManager.shared.setConnectDelegate(nil)
    }

    private init() {
        XWHearingAidManager.shared.setConnectDelegate(self)
    }
    
    func addConnectDelegate(_ delegate: XWConnectDeviceDelegate) {
        addConnectDelegate(delegate, insertToFirst: false)
    }
    
    func addConnectDelegate(_ delegate: XWConnectDeviceDelegate, insertToFirst: Bool) {
        for iItem in connectDelegateList {
            if iItem === delegate {
                return
            }
        }
        if insertToFirst {
            connectDelegateList.insert(delegate, at: 0)
        } else {
            connectDelegateList.append(delegate)
        }
    }
    
    func removeConnectDelegate(_ delegate: XWConnectDeviceDelegate) {
        connectDelegateList.removeAll(where: { $0 === delegate })
    }
    
    func removeAllConnectDelegate() {
        connectDelegateList.removeAll()
    }
    
    // MARK: - -------------
    func getLeftRightDeviceInfo(mergeMacDevice: XWDeviceModel) -> (leftDeviceInfo: XWDeviceModel?, rightDeviceInfo: XWDeviceModel?) {
        let (leftMac, rightMac) = AppFunctionHelper.getSeparateMac(mergeMac: mergeMacDevice.mac)
        var leftDeviceInfo: XWDeviceModel? = nil
        var rightDeviceInfo: XWDeviceModel? = nil
        if !leftMac.isEmpty, !rightMac.isEmpty {
            let leftReqDevice = mergeMacDevice.clone()
            leftReqDevice.devicePort = .left
            leftReqDevice.mac = leftMac
            leftDeviceInfo = leftReqDevice

            let rightReqDevicde = mergeMacDevice.clone()
            rightReqDevicde.devicePort = .right
            rightReqDevicde.mac = rightMac
            rightDeviceInfo = rightReqDevicde
        } else if !leftMac.isEmpty {
            let leftReqDevice = mergeMacDevice.clone()
            leftReqDevice.devicePort = .left
            leftReqDevice.mac = leftMac
            leftDeviceInfo = leftReqDevice
        } else if !rightMac.isEmpty {
            let rightReqDevicde = mergeMacDevice.clone()
            rightReqDevicde.devicePort = .right
            rightReqDevicde.mac = rightMac
            rightDeviceInfo = rightReqDevicde
        }
        
        return (leftDeviceInfo, rightDeviceInfo)
    }
    
    func getLeftRightDeviceControlInfo(mergeMacDevice: XWDeviceModel) -> (leftControlInfo: XWHAControlModel?, rightControlInfo: XWHAControlModel?) {
        var leftControl: XWHAControlModel?
        var rightControl: XWHAControlModel?
        let (leftDeviceInfo, rightDeviceInfo) = getLeftRightDeviceInfo(mergeMacDevice: mergeMacDevice)
        if let leftInfo = leftDeviceInfo {
            leftControl = XWHAControlModel.getConrolModel(with: leftInfo)
        }
        if let rightInfo = rightDeviceInfo {
            rightControl = XWHAControlModel.getConrolModel(with: rightInfo)
        }
        
        return (leftControl, rightControl)
    }
    
    func getHADeviceInfo(mergeMacDevice: XWDeviceModel) -> XWHAModel? {
        let (leftCtrl, rightCtrl) = getLeftRightDeviceControlInfo(mergeMacDevice: mergeMacDevice)
        if leftCtrl == nil, rightCtrl == nil {
            return nil
        }
        
        let retHa = XWHAModel()
        retHa.leftDevice = leftCtrl
        retHa.rightDevice = rightCtrl
        
        return retHa
    }
    
}

// MARK: - XWConnectDeviceDelegate
extension XWHADeviceCenter: XWConnectDeviceDelegate {
    
    /// 获取设备连接信息
    /// - Parameters:
    ///   - device: 连接的设备
    ///   - connectState: 连接状态
    func receiveDeviceConnectInfo(device: XWDeviceModel, connectState: XWDeviceConnectState, userInfo: [String : Any]?, error: ResultError?) {
        if let error = error {
            log.error("设备连接错误 error = \(error) \n")
            
            if error.code == disconnectAudioBleErrorCode {
                log.error("未连接经典蓝牙")
                
//                PopoverManager.showDeviceBTDisconnectDialog()
            }
            
            for iItem in connectDelegateList {
                iItem.receiveDeviceConnectInfo(device: device, connectState: connectState, userInfo: userInfo, error: error)
            }
            return
        }
        
        switch connectState {
        case .disconnect:
            break

        case .connecting:
            break

        case .connected:
            if let tHaDevice = conHaDevice {
//                deviceInUse = tHaDevice
//                XWHADataManager.shared.setCurrentHADevice(tHaDevice)
                
//                reportBindDevice()
                if let one = tHaDevice.oneDevice {
                    let reqDevice = one.clone()
                    reqDevice.mac = conHaDevice?.getMergeMac() ?? reqDevice.mac
//                    let isOk = userDeviceListManager.contains(mergeMacDevice: reqDevice)
//                    if isOk {
//                        break
//                    }
                    
                    userDeviceListManager.bindDevice(reqDevice: reqDevice) { [weak self] isOk, errorMsg in
                        guard let self = self else {
                            return
                        }
                        
                        if !isOk {
                            self.disconnectDevice()
                            if let errorMsg = errorMsg, !errorMsg.isEmpty {
                                DispatchQueue.main.async {
                                    UIApplication.appKeyWindow?.makeToast(errorMsg)
                                }
                            }
                            return
                        }
                        
                        for iItem in self.connectDelegateList {
                            iItem.receiveDeviceConnectInfo(device: device, connectState: connectState, userInfo: userInfo, error: error)
                        }
                        AppInnerNotificationManager.postConnectedDeviceListNeedUpdateNotification(object: true)
                    }
                    return
                }
            }
        }
        
        for iItem in connectDelegateList {
            iItem.receiveDeviceConnectInfo(device: device, connectState: connectState, userInfo: userInfo, error: error)
        }
    }
    
    /// 获取设备断开连接信息
    /// - Parameters:
    ///   - device: 连接的设备
    func receiveDisconnectDevice(device: XWDeviceModel?) {
        deviceInUse = nil
        for iItem in connectDelegateList {
            iItem.receiveDisconnectDevice(device: device)
        }
    }
    
    /// 获取设备数据
    /// - Parameters:
    ///   - device: 连接的设备
    ///   - error: 错误信息
    func receiveDeviceResponseInfo(device: XWDeviceModel, userInfo: [String : Any]?, error: ResultError?) {
        for iItem in connectDelegateList {
            iItem.receiveDeviceResponseInfo(device: device, userInfo: userInfo, error: error)
        }
    }
    
}

// MARK: - 设备连接
extension XWHADeviceCenter {
    
    // 连接设备
    func connectDevice() {
        guard let reqDevice = htDevice else {
            return
        }
        
        connectDevice(reqDevice: reqDevice)
    }
    
    // 连接设备
    func connectDevice(reqDevice: XWDeviceModel) {
        let cmdId = "连接设备"
        if reqDevice.deviceModelType == .none {
            log.error("\(cmdId), 设备型号为空")
            return
        }
        
        var reqDevicePort = XWDevicePortType.none

        let (leftReqDevice, rightReqDevice) = getLeftRightDeviceInfo(mergeMacDevice: reqDevice)
        
        let reqMac = reqDevice.mac
        let conMergeMac = conHaDevice?.getMergeMac() ?? ""
        if let _ = conHaDevice?.oneDevice {
            if reqMac.compare(conMergeMac, options: .caseInsensitive) == .orderedSame {
                if let conHaDevice = conHaDevice {
                    if let one = conHaDevice.oneDisconnectDevice {
                        reqDevicePort = one.devicePort
                    }
                } else {
                    reqDevicePort = XWDevicePortType.none
                }
            } else {
                disconnectDevice()
            }
        }
        
        if leftReqDevice == nil, rightReqDevice == nil {
            log.error("\(cmdId), leftReqDevice = nil, rightReqDevice = nil")
            return
        }

        deviceManager.connect(devicePort: reqDevicePort, leftReqDevice: leftReqDevice, rightReqDevice: rightReqDevice)
    }
    
    // 断开连接
    func disconnectDevice() {
        let one = conHaDevice?.oneDevice ?? XWDeviceModel()
        deviceManager.disconnect(devicePort: .none, leftReqDevice: conHaDevice?.leftDevice, rightReqDevice: conHaDevice?.rightDevice)
        
        receiveDeviceConnectInfo(device: one, connectState: .disconnect, userInfo: nil, error: nil)
    }
    
}

// MARK: - 设备功能获取/设置
extension XWHADeviceCenter {
    
    func setVolume(devicePort: XWDevicePortType, volume: Int, completion: ((_ isOk: Bool) -> Void)?) {
        XWHearingAidManager.shared.setVolume(devicePort: devicePort, volume: volume) { result in
            handleResult(result) { [weak self] tRes in
                guard let self = self else {
                    return
                }
                
                self.conHaDevice?.setVolume(devicePort: devicePort, volume: volume)
                completion?(true)
            } failureHandler: { [weak self] tError in
                guard let _ = self else {
                    return
                }
                completion?(false)
            }
        }
    }
    
    func setVolumeSync(isSync: Bool, completion: ((_ isOk: Bool) -> Void)?) {
        XWHearingAidManager.shared.setVolumeSync(isSync: isSync) { result in
            handleResult(result) { [weak self] tRes in
                guard let self = self else {
                    return
                }
                
                self.conHaDevice?.setVolumeSync(isSync: isSync)
                completion?(true)
            } failureHandler: { [weak self] tError in
                guard let _ = self else {
                    return
                }
                
                completion?(false)
            }
        }
    }
    
}
